﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Luminal;
using Luminoise.Properties;

namespace Luminoise
{
    public static class NoiseCore
    {
        const int permSize = 256;

        static Dictionary<int, MemoryObject> permCache = new Dictionary<int, MemoryObject>();

        public static Context Context { get; private set; }
        public static CommandQueue CommandQueue { get; private set; }
        public static string IncludeCode { get; private set; }

        static NoiseCore()
        {
            AppDomain.CurrentDomain.ProcessExit += new EventHandler(OnExit);

            Context = new Context(PlatformIdentifier.Default, DeviceType.Default);
            CommandQueue = new CommandQueue(Context, Context.Devices[0], new CommandQueueDescription(false, false));
            IncludeCode = Resources.Include;
        }

        static void OnExit(object sender, EventArgs e)
        {
            Context.Dispose();
            CommandQueue.Dispose();

            foreach (MemoryObject perm in permCache.Values)
                perm.Dispose();

            ObjectTracker.Objects.ToArray();
        }

        public static MemoryObject GetPermutationBuffer(int seed)
        {
            if (!permCache.ContainsKey(seed))
                permCache.Add(seed, GeneratePerm(seed));

            return permCache[seed];
        }

        static MemoryObject GeneratePerm(int seed)
        {
            Random random = new Random(seed);
            
            List<int> permList = new List<int>();
            for (int i = 0; i < permSize; i++)
                permList.Add(i);

            int[] perm = new int[permSize];
            for (int i = 0; i < permSize; i++)
            {
                int index = random.Next(0, permList.Count);
                perm[i] = permList[index];
                permList.RemoveAt(index);
            }

            return MemoryObject.CreateBuffer<int>(Context, MemoryAccessFlags.ReadOnly, perm);
        }
    }
}
